package sort;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 排序辅助类
 * 检验排序是否正确，排序的耗时
 */
public class SortHelper {
    //获取随机数对象
    private static final ThreadLocalRandom random = ThreadLocalRandom.current();

    /**
     * 生成一个长度为n的随机数数组
     * 随机数的范围在[left, right]之间
     * @param n
     * @param left
     * @param right
     * @return
     */
    public static int[] generateRandomArray(int n, int left, int right) {
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = random.nextInt(left, right);
        }
        return arr;
    }

    /**
     * 生成一个长度为n的近乎有序的数组
     * @param n
     * @param times 交换次数决定有序性
     * @return
     */
    public static int[] generateSortedArray(int n, int times) {
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = i;
        }
        //交换部分元素
        for(int i = 0; i < times; i++){
            int a = random.nextInt(n);
            int b = random.nextInt(n);
            arr[a] = arr[a] + arr[b] - (arr[b] = arr[a]);
        }
        return arr;
    }

    //生成一个深拷贝数组
    public static int[] arrCopy(int[] arr) {
        return Arrays.copyOf(arr, arr.length);
    }

    /**
     * 根据传入的方法名称，调用这个方法，需要借助反射
     * 根据其它类中的方法名，调用排序方法对arr数组进行排序
     * @param sortName
     * @param arr
     */
    public static void testSort(String sortName, int[] arr) {
        Class<SevenSort> cls = SevenSort.class;
        try {
            Method method = cls.getDeclaredMethod(sortName, int[].class);
            long start = System.nanoTime();
            method.invoke(null, arr);
            long end = System.nanoTime();
            if(isSorted(arr)){
                System.out.println(sortName + "排序结束，共耗时：" + (end-start)/1000000.0 + "ms");
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //检验排序的正确性
    public static boolean isSorted(int[] arr) {
        for(int i = 0; i < arr.length - 1; i++){
            if(arr[i] > arr[i+1]){
                System.err.println("sort error!");
                return false;
            }
        }
        return true;
    }
}
